package com.whiteape.book.ui.activity;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.ContentObserver;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.PowerManager;
import android.provider.Settings;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.recyclerview.widget.RecyclerView;

import com.github.chrisbanes.photoview.OnPhotoTapListener;
import com.google.android.material.appbar.AppBarLayout;
import com.gyf.immersionbar.ImmersionBar;
import com.hwangjr.rxbus.RxBus;
import com.hwangjr.rxbus.annotation.Subscribe;
import com.hwangjr.rxbus.annotation.Tag;
import com.hwangjr.rxbus.thread.EventThread;
import com.whiteape.book.R;
import com.whiteape.book.common.RxEvent;
import com.whiteape.book.common.WaConstants;
import com.whiteape.book.contract.ComicReadContract;
import com.whiteape.book.core.manager.MediaStorageManager;
import com.whiteape.book.core.manager.ReadSettingManager;
import com.whiteape.book.model.bo.ChapterContentBo;
import com.whiteape.book.model.dto.CollectionMediaBean;
import com.whiteape.book.model.dto.DownloadTaskBean;
import com.whiteape.book.model.dto.MediaChapterBean;
import com.whiteape.book.model.dto.MediaRecordBean;
import com.whiteape.book.model.dto.SiteSourceBean;
import com.whiteape.book.model.type.CatalogOrderType;
import com.whiteape.book.model.type.ComicLoadFlag;
import com.whiteape.book.presenter.ComicReadPresenter;
import com.whiteape.book.ui.adapter.ComicCatalogAdapter;
import com.whiteape.book.ui.adapter.ComicReadAdapter;
import com.whiteape.book.ui.base.BaseMVPActivity;
import com.whiteape.book.ui.dialog.ComicReadSettingDialog;
import com.whiteape.book.utils.BrightnessUtils;
import com.whiteape.book.utils.DaoDbHelper;
import com.whiteape.book.utils.DisplayUtil;
import com.whiteape.book.utils.LogUtils;
import com.whiteape.book.utils.RxUtils;
import com.whiteape.book.utils.ScreenUtils;
import com.whiteape.book.utils.SimilarityUtil;
import com.whiteape.book.utils.StringUtils;
import com.whiteape.book.utils.SystemBarUtils;
import com.whiteape.book.utils.ToastUtils;
import com.whiteape.book.widget.LoadingText;
import com.whiteape.book.widget.PreCacheLayoutManager;
import com.whiteape.book.widget.ZoomRecyclerView;
import com.whiteape.book.widget.itemdecoration.DividerItemDecoration;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import butterknife.BindView;
import io.reactivex.disposables.Disposable;

import static android.view.View.GONE;
import static android.view.View.VISIBLE;

public class ComicReadActivity extends BaseMVPActivity<ComicReadContract.Presenter> implements
        ComicReadContract.View, OnPhotoTapListener, ComicReadAdapter.OnLazyLoadListener {

    public static final String EXTRA_SHELF_BOOK = "extra_shelf_book";
    public static final String EXTRA_IS_IN_SHELF = "extra_is_in_shelf";
    public static final String EXTRA_CHAPTERS_LIST = "extra_chapter_list";
    public static final String EXTRA_JUMP_TO_CHAPTER_ID = "extra_jump_to_chapter_id";
    public static final String EXTRA_JUMP_TO_CHAPTER_TITLE = "extra_jump_to_chapter_title";
    public static final String EXTRA_JUMP_TO_CHAPTER_PAGE = "extra_jump_to_chapter_page";
    public static final int REQUEST_CHANGE_SOURCE = 2222;

    protected PreCacheLayoutManager mLayoutManager;
    // 注册 Brightness 的 uri
    private final Uri BRIGHTNESS_MODE_URI =
            Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_MODE);
    private final Uri BRIGHTNESS_URI =
            Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS);
    private final Uri BRIGHTNESS_ADJ_URI =
            Settings.System.getUriFor("screen_auto_brightness_adj");

    private static final int WHAT_CATEGORY = 1;
    private static final int WHAT_CHAPTER = 2;


    private CollectionMediaBean mCollectionMediaBean;
    private SiteSourceBean mSiteSourceBean;
//    private String mComicId;

    @BindView(R.id.read_dl_slide)
    DrawerLayout mDlSlide;
    @BindView(R.id.rl_content)
    RelativeLayout mRlContent;
    /*************top_menu_view*******************/
    @BindView(R.id.read_abl_top_menu)
    AppBarLayout mAblTopMenu;
    @BindView(R.id.read_recycle_view)
    ZoomRecyclerView mRvRead;
    @BindView(R.id.read_ll_bottom_menu)
    LinearLayout mLlBottomMenu;
    @BindView(R.id.read_tv_pre_chapter)
    TextView mTvPreChapter;
    @BindView(R.id.read_tv_next_chapter)
    TextView mTvNextChapter;
    @BindView(R.id.read_tv_catalog)
    TextView mTvCatalog;
    @BindView(R.id.read_tv_brightness)
    TextView mTvNightMode;
    //    @BindView(R.id.read_tv_setting)
//    TextView mTvSetting;
    @BindView(R.id.read_tv_change_source)
    TextView mTvChangeSource;
    @BindView(R.id.read_tv_download)
    TextView mTvDownload;
    @BindView(R.id.read_iv_catalog)
    ListView mLvCatalog;
    @BindView(R.id.tv_battery)
    TextView mTvBattery;
    @BindView(R.id.tv_time)
    TextView mTvTime;
    @BindView(R.id.tv_page)
    TextView mTvPage;
    @BindView(R.id.tv_chapter)
    TextView mTvChapter;
    @BindView(R.id.ll_loading)
    LinearLayout llLoading;
    @BindView(R.id.tv_catalog_order)
    TextView mTvCatalogOrder;
    @BindView(R.id.iv_catalog_order)
    ImageView mIvCatalogOrder;
    @BindView(R.id.loading_text)
    LoadingText mLoadingText;

    List<ChapterContentBo> mChapterContentBoList = new ArrayList<>();

    MediaRecordBean mMediaRecordBean = new MediaRecordBean();
    private ComicReadSettingDialog mSettingDialog;
    private Animation mTopInAnim;
    private Animation mTopOutAnim;
    private Animation mBottomInAnim;
    private Animation mBottomOutAnim;
    private ComicCatalogAdapter mCatalogAdapter;
    private ComicReadAdapter mComicReadAdapter;
    private List<MediaChapterBean> mCatalogRawDataList = new ArrayList<>();
    private Map<String, Integer> mChapterIndexRawMap = new HashMap<>();
    //控制屏幕常亮
    private PowerManager.WakeLock mWakeLock;

    //首次阅读（从阅读按钮进来的，而不是详情页点击目录具体章节进来的）
    private boolean readWhenInit = true;
    private int mStartX = 0;
    private int mStartY = 0;
    private boolean isMove = false;
    private boolean canTouch = true;
    // 唤醒菜单的区域
    private RectF mCenterRect = null;
    private MediaChapterBean mCurrentChapterBean;
    //    private int mLastTopPosition = 0;
//    private int mLastBottomPosition = 0;
    private int mJumpToChapterIndex = -1;
    /**
     * 加载上一章的阈值，就是本章往上面还有多少图片的时候，需要加载上一章
     */
    private final int LOAD_PRE_THRESHOLD = 3;
    /**
     * 加载下一章的阈值，就是本章往下面还有多少图片的时候，需要加载下一章
     */
    private final int LOAD_NEXT_THRESHOLD = 5;

    private MediaRecordBean mediaRecordBean;

    //启动activity传入的章节列表（如果从详情过来的，会带着这个，避免重复获取章节列表）
    public static List<MediaChapterBean> inputChapterBeanList;

    //启动activity传入的章节id，指定跳转到该章节
    private String inputChapterId;
    private String inputChapterTitle;
    private int inputChapterIndex = -1;
    private int inputPage;


    private CatalogOrderType mCatalogOrderType = CatalogOrderType.ORDER_ASC;

    public static void startActivity(Context context, CollectionMediaBean collectionMediaBean,
                                     List<MediaChapterBean> chapterBeanList,
                                     boolean isCollected, String chapterId) {
        startActivity(context, collectionMediaBean, chapterBeanList, isCollected, chapterId, null, 0);
    }

    public static void startActivity(Context context, CollectionMediaBean collectionMediaBean,
                                     List<MediaChapterBean> chapterBeanList,
                                     boolean isCollected, String chapterId,
                                     String chapterTitle, int page) {
        inputChapterBeanList = chapterBeanList;
        context.startActivity(new Intent(context, ComicReadActivity.class)
                        .putExtra(EXTRA_IS_IN_SHELF, isCollected)
                        .putExtra(EXTRA_SHELF_BOOK, collectionMediaBean)
//                .putExtra(EXTRA_CHAPTERS_LIST, (Serializable) chapterBeanList)
                        .putExtra(EXTRA_JUMP_TO_CHAPTER_ID, chapterId)
                        .putExtra(EXTRA_JUMP_TO_CHAPTER_TITLE, chapterTitle)
                        .putExtra(EXTRA_JUMP_TO_CHAPTER_PAGE, page)
        )
        ;
    }

    // 接收电池信息和时间更新的广播
    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED)) {
                int level = intent.getIntExtra("level", 0);
                mTvBattery.setText(level + "%");
            }
            // 监听分钟的变化
            else if (intent.getAction().equals(Intent.ACTION_TIME_TICK)) {
                updateTipsTime();
            }
        }
    };

    private ContentObserver mBrightObserver = new ContentObserver(new Handler()) {
        @Override
        public void onChange(boolean selfChange) {
            onChange(selfChange, null);
        }

        @Override
        public void onChange(boolean selfChange, Uri uri) {
            super.onChange(selfChange);

            // 判断当前是否跟随屏幕亮度，如果不是则返回
            if (selfChange || !mSettingDialog.isBrightFollowSystem()) return;

            // 如果系统亮度改变，则修改当前 Activity 亮度
            if (BRIGHTNESS_MODE_URI.equals(uri)) {
                LogUtils.d("亮度模式改变");
            } else if (BRIGHTNESS_URI.equals(uri) && !BrightnessUtils.isAutoBrightness(ComicReadActivity.this)) {
                LogUtils.d("亮度模式为手动模式 值改变");
                BrightnessUtils.setBrightness(ComicReadActivity.this, BrightnessUtils.getScreenBrightness(ComicReadActivity.this));
            } else if (BRIGHTNESS_ADJ_URI.equals(uri) && BrightnessUtils.isAutoBrightness(ComicReadActivity.this)) {
                LogUtils.d("亮度模式为自动模式 值改变");
                BrightnessUtils.setDefaultBrightness(ComicReadActivity.this);
            } else {
                LogUtils.d("亮度调整 其他");
            }
        }
    };

    /***************params*****************/
    private boolean isCollected = false; // isFromSDCard
    private boolean isNightMode = false;
    private boolean isFullScreen = false;
    private boolean isRegistered = false;


    @Override
    protected void initData(Bundle savedInstanceState) {
        super.initData(savedInstanceState);
        mCollectionMediaBean = getIntent().getParcelableExtra(EXTRA_SHELF_BOOK);
//        inputChapterBeanList = (List<MediaChapterBean>) getIntent().getSerializableExtra(EXTRA_CHAPTERS_LIST);
        inputChapterId = getIntent().getStringExtra(EXTRA_JUMP_TO_CHAPTER_ID);
        inputChapterTitle = getIntent().getStringExtra(EXTRA_JUMP_TO_CHAPTER_TITLE);
        inputPage = getIntent().getIntExtra(EXTRA_JUMP_TO_CHAPTER_PAGE, 0);


        isCollected = getIntent().getBooleanExtra(EXTRA_IS_IN_SHELF, false);
        isNightMode = ReadSettingManager.getInstance().isNightMode();
        isFullScreen = ReadSettingManager.getInstance().isFullScreen();

//        mComicId = mCollectionMediaBean.getId();
        mCollectionMediaBean.__setDaoSession(DaoDbHelper.getInstance().getSession());
        mSiteSourceBean = mCollectionMediaBean.getSiteSourceBean();

        //只有当前没有指定章节的时候，才会
        if (org.apache.commons.lang3.StringUtils.isEmpty(inputChapterId)) {
            readWhenInit = true;
        }
    }

    @Override
    protected void setUpToolbar(Toolbar toolbar) {
        super.setUpToolbar(toolbar);
        //设置标题
//        toolbar.setTitle(mCollectionMediaBean.getTitle());
        if (null != getSupportActionBar()) {
            getSupportActionBar().setTitle(mCollectionMediaBean.getTitle());
        }
        //半透明化StatusBar
        SystemBarUtils.transparentStatusBar(this);
    }


    @Override
    protected ComicReadContract.Presenter bindPresenter() {
        return new ComicReadPresenter();
    }

    @Override
    protected int getContentId() {
        return R.layout.activity_comic_read;
    }

    @Override
    protected void initImmersionBar() {
        super.initImmersionBar();
//        ImmersionBar.with(this)
//                .fitsSystemWindows(true)
//                .statusBarColor(R.color.black)
////                .navigationBarColor(R.color.black)
////                .barEnable(false)
//                .init();
    }

    @Override
    protected void initView() {
        super.initView();
        hideSystemBar();

        mDlSlide.setStatusBarBackground(R.color.black);
        mDlSlide.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
        //侧边打开后，返回键能够起作用
        mDlSlide.setFocusableInTouchMode(false);
        mSettingDialog = new ComicReadSettingDialog(this);

        setUpAdapter();

        //夜间模式按钮的状态
        toggleNightMode();

        //注册广播
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
        intentFilter.addAction(Intent.ACTION_TIME_TICK);
        registerReceiver(mReceiver, intentFilter);

        //设置当前Activity的Brightness
        if (ReadSettingManager.getInstance().isBrightnessAuto()) {
            BrightnessUtils.setDefaultBrightness(this);
        } else {
            BrightnessUtils.setBrightness(this, ReadSettingManager.getInstance().getBrightness());
        }

        //初始化屏幕常亮类
        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, ":keep bright");

        //隐藏StatusBar
//        mPvPage.post(this::hideSystemBar);

        //初始化TopMenu
        initTopMenu();

        //初始化BottomMenu
        initBottomMenu();

        //初始化底部导航栏
        initNavigationBar();

        updateTipsTime();

        mComicReadAdapter = new ComicReadAdapter(R.layout.item_comic_read, mChapterContentBoList);
        mComicReadAdapter.setTapListener(this);
        mComicReadAdapter.setLazyLoadListener(this);
        initLayoutManager();
        ((ZoomRecyclerView) mRvRead).setEnableScale(true);
        mRvRead.setAdapter(mComicReadAdapter);
        mRvRead.setLayoutManager(mLayoutManager);
        mRvRead.addItemDecoration(new DividerItemDecoration(this));

        mLoadingText.setBitmap(R.mipmap.loading_text);
        mLoadingText.start();
        mRvRead.setPadding(0, ImmersionBar.getStatusBarHeight(this), 0, 0);

    }

    private void initLayoutManager() {
        mLayoutManager = new PreCacheLayoutManager(this);
//        mLayoutManager.setOrientation(turn == PreferenceManager.READER_TURN_ATB ? LinearLayoutManager.VERTICAL : LinearLayoutManager.HORIZONTAL);
//        mLayoutManager.setReverseLayout(turn == PreferenceManager.READER_TURN_RTL);
        mLayoutManager.setExtraSpace(2);
    }

    private void initNavigationBar() {
//        getWindow().setNavigationBarColor(R.color.black);
        SystemBarUtils.setNavigationBarColor(this, 0xff000000);
        SystemBarUtils.transparentStatusBar(this);
//        SystemBarUtils.hideStableStatusBar(this);

    }

    private void setUpAdapter() {
        mCatalogAdapter = new ComicCatalogAdapter();
        mLvCatalog.setAdapter(mCatalogAdapter);
        mLvCatalog.setFastScrollEnabled(true);
    }

    /**
     * 这里就是 隐藏沉浸式的status bar后，内容会和status bar重叠的问题，把内容的padding设置为status bar
     * 的高度，即把整体内容往下拉一个status bar的高度即可
     */
    private void initTopMenu() {
        if (Build.VERSION.SDK_INT >= 19) {
            mAblTopMenu.setPadding(0, ScreenUtils.getStatusBarHeight(), 0, 0);
        }
    }

    private void initBottomMenu() {
        //判断是否全屏
        if (ReadSettingManager.getInstance().isFullScreen()) {
            //还需要设置mBottomMenu的底部高度
            ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) mLlBottomMenu.getLayoutParams();
            params.bottomMargin = ScreenUtils.getNavigationBarHeight();
            mLlBottomMenu.setLayoutParams(params);
        } else {
            //设置mBottomMenu的底部距离
            ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) mLlBottomMenu.getLayoutParams();
            params.bottomMargin = 0;
            mLlBottomMenu.setLayoutParams(params);
        }
    }

    private void toggleNightMode() {
        if (isNightMode) {
            mTvNightMode.setText(StringUtils.getString(R.string.wa_mode_morning));
            Drawable drawable = ContextCompat.getDrawable(this, R.mipmap.ic_read_menu_morning);
            mTvNightMode.setCompoundDrawablesWithIntrinsicBounds(null, drawable, null, null);
        } else {
            mTvNightMode.setText(StringUtils.getString(R.string.wa_mode_night));
            Drawable drawable = ContextCompat.getDrawable(this, R.mipmap.ic_read_menu_night);
            mTvNightMode.setCompoundDrawablesWithIntrinsicBounds(null, drawable, null, null);
        }
    }

    private void showSystemBar() {
        //显示
        SystemBarUtils.showUnStableStatusBar(this);
        if (isFullScreen) {
            SystemBarUtils.showUnStableNavBar(this);
        }
    }

    private void hideSystemBar() {
//        //隐藏
        SystemBarUtils.hideStableStatusBar(this);
        if (isFullScreen) {
            SystemBarUtils.hideStableNavBar(this);
        }
    }

    // 注册亮度观察者
    private void registerBrightObserver() {
        try {
            if (mBrightObserver != null) {
                if (!isRegistered) {
                    final ContentResolver cr = getContentResolver();
                    cr.unregisterContentObserver(mBrightObserver);
                    cr.registerContentObserver(BRIGHTNESS_MODE_URI, false, mBrightObserver);
                    cr.registerContentObserver(BRIGHTNESS_URI, false, mBrightObserver);
                    cr.registerContentObserver(BRIGHTNESS_ADJ_URI, false, mBrightObserver);
                    isRegistered = true;
                }
            }
        } catch (Throwable throwable) {
            LogUtils.e("register mBrightObserver error! " + throwable);
        }
    }

    //解注册
    private void unregisterBrightObserver() {
        try {
            if (mBrightObserver != null) {
                if (isRegistered) {
                    getContentResolver().unregisterContentObserver(mBrightObserver);
                    isRegistered = false;
                }
            }
        } catch (Throwable throwable) {
            LogUtils.e("unregister BrightnessObserver error! " + throwable);
        }
    }

    /**
     * 切换菜单栏的可视状态
     * 默认是隐藏的
     */
    private void toggleMenu(boolean hideStatusBar) {
        initMenuAnim();

        if (mAblTopMenu.getVisibility() == View.VISIBLE) {
            //关闭
            mAblTopMenu.startAnimation(mTopOutAnim);
            mLlBottomMenu.startAnimation(mBottomOutAnim);
            mAblTopMenu.setVisibility(GONE);
            mLlBottomMenu.setVisibility(GONE);
//            mTvPageTip.setVisibility(GONE);

//            if (hideStatusBar) {
            hideSystemBar();
//            }
        } else {
            mAblTopMenu.setVisibility(View.VISIBLE);
            mLlBottomMenu.setVisibility(View.VISIBLE);
            mAblTopMenu.startAnimation(mTopInAnim);
            mLlBottomMenu.startAnimation(mBottomInAnim);

//            showSystemBar();
            hideSystemBar();
        }
    }


    //初始化菜单动画
    private void initMenuAnim() {
        if (mTopInAnim != null) return;

        mTopInAnim = AnimationUtils.loadAnimation(this, R.anim.slide_top_in);
        mTopOutAnim = AnimationUtils.loadAnimation(this, R.anim.slide_top_out);
        mBottomInAnim = AnimationUtils.loadAnimation(this, R.anim.slide_bottom_in);
        mBottomOutAnim = AnimationUtils.loadAnimation(this, R.anim.slide_bottom_out);
        //退出的速度要快
        mTopOutAnim.setDuration(200);
        mBottomOutAnim.setDuration(200);
    }

    @Override
    protected void startLogic() {
        super.startLogic();
        llLoading.setVisibility(VISIBLE);


//        List<MediaChapterBean>  inputChapterBeanList = mCollectionMediaBean.getMediaChapterList();
        if (inputChapterBeanList != null && !inputChapterBeanList.isEmpty()) {
            //表示传入进来自带章节信息，那么不用手动获取了
            showCatalog(inputChapterBeanList);
            return;
        }
        if (isCollected) {
            Disposable disposable = MediaStorageManager.getInstance()
                    .getMediaChaptersInRx(mCollectionMediaBean.getId())
                    .compose(RxUtils::toSimpleSingle)
                    .subscribe(
                            (mediaChapterBeanList, throwable) -> {
                                // 设置 CollBook
//                                mPageLoader.getShelfMedia().setMediaChapterList(mediaChapterBeanList);
                                // 刷新章节列表
//                                mPageLoader.refreshChapterList();
                                if (mediaChapterBeanList == null || mediaChapterBeanList.isEmpty()) {
                                    // 收藏了，但是这里发现没有目录信息了， why?
                                    mPresenter.loadWebCatalog(mSiteSourceBean, mCollectionMediaBean);
                                    return;
                                }
                                showCatalog(mediaChapterBeanList);
                                // 如果是网络数据并被标记更新的，则从网络下载目录
                                // TODO 这个 getIfUpdated在哪儿更新的?
                                if (mCollectionMediaBean.getIfUpdated() && !mCollectionMediaBean.getIfLocal()) {
                                    mPresenter.updateWebCatalog(mSiteSourceBean, mCollectionMediaBean);
                                }
                                LogUtils.e(throwable);
                            }
                    );
            addDisposable(disposable);
        } else {
            // 从网络中获取目录
            mPresenter.loadWebCatalog(mSiteSourceBean, mCollectionMediaBean);
        }

    }

    private void chapterToMap(List<MediaChapterBean> mediaChapterBeanList) {
        mChapterIndexRawMap.clear();
        for (int i = 0; i < mediaChapterBeanList.size(); i++) {
            mChapterIndexRawMap.put(mediaChapterBeanList.get(i).getId(), i);
        }
    }

    @Override
    public void loadCatalogFailed() {
        //TODO 加载失败，请重试
    }

    /**
     * 仅仅只是更新目录信息
     *
     * @param bookChapterList
     */
    @Override
    public void updateCatalog(List<MediaChapterBean> bookChapterList) {
        mCatalogAdapter.clear();
        mCatalogAdapter.addItems(bookChapterList);
        mCatalogRawDataList.clear();
        mCatalogRawDataList.addAll(bookChapterList);
        mCollectionMediaBean.setMediaChapterList(bookChapterList);
        chapterToMap(bookChapterList);

        if (isCollected) {
            MediaStorageManager.getInstance().saveMediaChaptersWithAsync(bookChapterList);
        }
    }


    @Override
    public void updateCatalogFailed() {

    }

    //查找跟输入的需要跳转的title更为接近的标题所在的chapterId
    private String getMatchedChapterId(List<MediaChapterBean> mediaChapterBeanList) {

        double similar = 0.0d;
        int similarIndex = 0;
        String similarChapterId = null;
        for (int i = 0; i < mediaChapterBeanList.size(); i++) {
            MediaChapterBean chapterBean = mediaChapterBeanList.get(i);
            String tempChapterTitle = chapterBean.getName().trim();
            if (tempChapterTitle.equals(inputChapterTitle)) {
                return chapterBean.getId();
            }
            double tmpSim = SimilarityUtil.sim(inputChapterTitle.replaceAll("[第章话話🔐]", ""), tempChapterTitle.replaceAll("[第章话話🔐]", ""));
            //如果相似度接近，那么用索引值更接近的那个
            if (tmpSim > similar || ((tmpSim == similar) && Math.abs(i - inputChapterIndex) < Math.abs(i - similarIndex))) {
                similar = tmpSim;
                similarIndex = i;
                similarChapterId = chapterBean.getId();
            }
        }
        //如果没有完全匹配的，那么按照最大相似度来匹配
        //TODO 按照标题所在index来匹配？
        return similarChapterId;

    }

    @Override
    public void showCatalog(List<MediaChapterBean> bookChapterList) {

        updateCatalog(bookChapterList);

        int loadSize = 2;
        if (bookChapterList.size() < loadSize) {
            loadSize = bookChapterList.size();
        }

        //TODO rx?
        // title 和 id只会有一个，如果有title，那么没有chapterId，需要生成chapterId
        if (!org.apache.commons.lang3.StringUtils.isEmpty(inputChapterTitle)) {
            inputChapterId = getMatchedChapterId(bookChapterList);

        }
        if (!org.apache.commons.lang3.StringUtils.isEmpty(inputChapterId)) {
            int chapterIndex = getChapterIndexInRawData(inputChapterId);
            skipToChapter(chapterIndex);
            return;

        }
        //判断是否有本地记录以及本地缓存的章节内容,有的话，跳转到本地缓存
        mediaRecordBean = MediaStorageManager.getInstance().getMediaRecord(mCollectionMediaBean.getId());
        if (mediaRecordBean != null) {
            int chapterIndex = mediaRecordBean.getChapter();
            String chapterTitle = bookChapterList.get(chapterIndex).getName();
            //有本地章节内容缓存
            List<ChapterContentBo> contentBoList = MediaStorageManager.getInstance().getComicChapterInfoBean(mCollectionMediaBean.getId(), chapterTitle);
            if (contentBoList != null && contentBoList.size() > 0) {
                if (chapterIndex < mChapterContentBoList.size()) {
                    finishChapter(contentBoList, ComicLoadFlag.LOAD_NEXT, mChapterContentBoList.get(chapterIndex).getChapterId());
                } else {
                    finishChapter(contentBoList, ComicLoadFlag.LOAD_NEXT, null);
                }
                return;
            }
        }
        mPresenter.loadChapter(mSiteSourceBean, mCollectionMediaBean, mCatalogRawDataList.subList(0, loadSize), ComicLoadFlag.LOAD_NEXT);
    }

    /**
     * 找到下一个需要插入的章节目录的起始地址
     * 如果当前是章节1，2,3，4，且显示的是2，那么来了一个章节5的话，需要插到4后面而不是现在的2后面
     *
     * @param chapterIndex
     * @return
     */
    private int findNextInsertPosition(int chapterIndex) {
        int i;
        for (i = 0; i < mChapterContentBoList.size(); i++) {
            Integer index = mChapterIndexRawMap.get(mChapterContentBoList.get(i).getChapterId());
            //TODO 问题是，为什么会有index为null的情况？
            if (index != null && index > chapterIndex) {
                break;
            }
        }
        return i;


    }

    /**
     * 找到上一个需要插入的章节目录的起始地址
     * 如果当前是章节6,7,8,9且显示的是8，那么来了一个章节5的话，需要插到6前面而不是现在的8前面
     *
     * @param chapterIndex
     * @return
     */
    private int findPreInsertPosition(int chapterIndex) {
        int i;
        for (i = mChapterContentBoList.size() - 1; i > 0; i--) {
            if (getChapterIndexInRawData(mChapterContentBoList.get(i).getChapterId()) < chapterIndex) {
                break;
            }
        }
        return i;
    }

    /**
     * 一系列内容bo，可能是需要lazy loading的img，但是，一个章节下的，全部已经返回
     * <p>
     * 可能有的章节名字重叠，因此使用请求中的chapterId
     *
     * @param chapterContentBoList
     */
    @Override
    public void finishChapter(List<ChapterContentBo> chapterContentBoList, ComicLoadFlag flag, String requestChapterId) {

        if (chapterContentBoList == null || chapterContentBoList.size() == 0) {
            return;
        }
        //TODO lazy load start here?
        int chapterIndex = getChapterIndexInRawData(requestChapterId != null ? requestChapterId : chapterContentBoList.get(0).getChapterId());
        int curChapterIndex = 0;
        if (!mComicReadAdapter.getData().isEmpty()) {
            ChapterContentBo currentChapter = mComicReadAdapter.getData().get(mLayoutManager.findFirstVisibleItemPosition());
            if (currentChapter == null) {
                //有问题
                LogUtils.e("找不到当前章节信息 mLastTopPosition=" + mLayoutManager.findFirstVisibleItemPosition());
                return;
            }
            curChapterIndex = getChapterIndexInRawData(currentChapter.getChapterId());
        }
//        int insertPrePosition = mLastTopPosition - curImagePartNumInChapter;
//        int insertNextPosition = mLastTopPosition + curImagePartTotal - curImagePartNumInChapter;
        int insertPrePosition = findPreInsertPosition(chapterIndex);
        int insertNextPosition = findNextInsertPosition(chapterIndex);

        //在当前章节的前面插入
        if (chapterIndex < curChapterIndex) {
//            mLastTopPosition = chapterContentBoList.size();
            mRvRead.post(() -> {
                mChapterContentBoList.addAll(insertPrePosition, chapterContentBoList);
                mComicReadAdapter.notifyItemRangeInserted(0, chapterContentBoList.size());
                updateTips();
            });
//            mLastTopPosition += chapterContentBoList.size();
        } else {
            mRvRead.post(() -> {
                mChapterContentBoList.addAll(insertNextPosition, chapterContentBoList);
                mComicReadAdapter.notifyItemRangeInserted(insertNextPosition, chapterContentBoList.size());
                updateTips();
            });
        }
//        updateTips(mCatalogRawDataList.get(chapterIndex).getName(), "1/" + chapterContentBoList.get(0).getPartTotal());
        //如果当前是其他地方跳转进来，需要直接跳转到某个章节（换源）的某一页，或者是有阅读记录的
        if (inputPage != 0 || (readWhenInit && mediaRecordBean != null)) {
            //有阅读记录
            readWhenInit = false;
            int needToJumpToPage = inputPage == 0 ? mediaRecordBean.getPagePos() : inputPage;
            mRvRead.post(() -> {
                mRvRead.scrollToPosition(needToJumpToPage);
                updateTips();
            });

        }
        if (mJumpToChapterIndex == -1) {
            llLoading.setVisibility(GONE);
        } else if (mJumpToChapterIndex >= 0 && chapterIndex == mJumpToChapterIndex) {
            int scrollTo = chapterIndex < curChapterIndex ? insertPrePosition : insertNextPosition;
            mRvRead.scrollToPosition(scrollTo);
            llLoading.setVisibility(GONE);
            mJumpToChapterIndex = -1;
//            mLastTopPosition = scrollTo;
        }
//        mComicReadAdapter.notifyDataSetChanged();
    }

    @Override
    public void onBackPressed() {
        if (mAblTopMenu.getVisibility() == View.VISIBLE) {
            // 非全屏下才收缩，全屏下直接退出
            if (!ReadSettingManager.getInstance().isFullScreen()) {
                toggleMenu(true);
                return;
            }
        } else if (mSettingDialog.isShowing()) {
            mSettingDialog.dismiss();
            return;
        } else if (mDlSlide.isDrawerOpen(GravityCompat.START)) {
            mDlSlide.closeDrawer(GravityCompat.START);
            return;
        }

        mCollectionMediaBean.__setDaoSession(DaoDbHelper.getInstance().getSession());
        if (!mCollectionMediaBean.getIfLocal() && !isCollected
                && !mCollectionMediaBean.getMediaChapterList().isEmpty()) {
            AlertDialog alertDialog = new AlertDialog.Builder(this)
                    .setTitle("加入书架")
                    .setMessage("喜欢本书就加入书架吧")
                    .setPositiveButton("确定", (dialog, which) -> {
                        //设置为已收藏
                        saveMedia();
                        exit();
                    })
                    .setNegativeButton("取消", (dialog, which) -> {
                        exit();
                    }).create();
            alertDialog.show();
        } else {
            exit();
        }
    }

    private void saveMedia() {
        isCollected = true;
        mCollectionMediaBean.setLastRead(StringUtils.
                dateConvert(System.currentTimeMillis(), WaConstants.FORMAT_BOOK_DATE));

        MediaStorageManager.getInstance()
                .saveCollectionMedia(mCollectionMediaBean);

        RxBus.get().post(RxEvent.MEDIA_COLLECTION_ADD, mCollectionMediaBean);
    }

    // 退出
    private void exit() {
        Intent result = new Intent();
        result.putExtra(MediaDetailActivity.RESULT_IS_COLLECTED, isCollected);
        setResult(Activity.RESULT_OK, result);
        // 退出
        super.onBackPressed();
    }

    @Override
    protected void onStart() {
        super.onStart();
        registerBrightObserver();
    }

    @Override
    protected void onResume() {
        super.onResume();
        mWakeLock.acquire();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mWakeLock.release();
        if (isCollected) {
            saveRecord();
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        unregisterBrightObserver();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(mReceiver);


        //TODO
//        mHandler.removeMessages(WHAT_CATEGORY);
//        mHandler.removeMessages(WHAT_CHAPTER);
//
//        mPageLoader.closeBook();
//        mPageLoader = null;
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        boolean isVolumeTurnPage = ReadSettingManager
                .getInstance().isVolumeTurnPage();
        switch (keyCode) {
            case KeyEvent.KEYCODE_VOLUME_UP:
                if (isVolumeTurnPage) {
                    //TODO
//                    return mPageLoader.skipToPrePage();
                }
                break;
            case KeyEvent.KEYCODE_VOLUME_DOWN:
                if (isVolumeTurnPage) {
                    //TODO
//                    return mPageLoader.skipToNextPage();
                }
                break;
        }
        return super.onKeyDown(keyCode, event);
    }

    /**
     * 跳转到前一章节
     *
     * @return
     */
    private boolean skipToPreChapter() {
        if (mJumpToChapterIndex > 0) {
            //当前已经有一个跳转请求了，先不做其他跳转
            return false;
        }
        int chapterIndexInRawData = getChapterIndexInRawData();
        if (chapterIndexInRawData > 0) {
            skipToChapter(getChapterIndexInRawData(chapterIndexInRawData - 1));
            return true;
        }
        return false;

    }

    /**
     * 跳转到下一章节
     *
     * @return
     */
    private boolean skipToNextChapter() {
        if (mJumpToChapterIndex > 0) {
            //当前已经有一个跳转请求了，先不做其他跳转
            return false;
        }
        int chapterIndexInRawData = getChapterIndexInRawData();
        if (chapterIndexInRawData < mCatalogRawDataList.size() - 1) {
            skipToChapter(getChapterIndexInRawData(chapterIndexInRawData + 1));
            return true;
        }
        return false;


    }

    private void skipToChapter(int position) {
        try {
            llLoading.setVisibility(VISIBLE);
            //如果是跳跃到目录的话，那么直接清除重新开始
            int size = mComicReadAdapter.getData().size();
            mComicReadAdapter.getData().clear();
//            mComicReadAdapter.notifyDataSetChanged();
            mComicReadAdapter.notifyItemMoved(0, size);
//            mLastTopPosition = 0;
            int index = getChapterIndexInRawData(position);
            mJumpToChapterIndex = index;
            updateTips(mCatalogRawDataList.get(index).getName(), "");
            int end = index < mCatalogRawDataList.size() - 1 ? index + 2 : index + 1;

            mPresenter.loadChapter(mSiteSourceBean, mCollectionMediaBean, mCatalogRawDataList.subList(index, index + 1), ComicLoadFlag.LOAD_JUMP_CHAPTER);
//            mPresenter.loadChapter(mSiteSourceBean, mComicId, mCatalogRawDataList.subList(index > 0 ? index - 1 : index, end), ComicLoadFlag.LOAD_JUMP_CHAPTER);
//            if (index > 0) {
//
//                mPresenter.loadChapter(mSiteSourceBean, mComicId, mCatalogRawDataList.subList(index - 1, index), ComicLoadFlag.LOAD_JUMP_CHAPTER);
//            }


        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 目录排序事件
     */
    private void initCatalogOrderEvent() {
        mIvCatalogOrder.setOnClickListener(view -> catalogOrderEvent());
        mTvCatalogOrder.setOnClickListener(view -> catalogOrderEvent());
    }

    private void catalogOrderEvent() {
        switch (mCatalogOrderType) {
            case ORDER_ASC:
                mIvCatalogOrder.setImageResource(R.mipmap.ic_read_catalog_order_desc);
                mTvCatalogOrder.setText(getResources().getString(R.string.wa_read_catalog_order_desc));
                mCatalogOrderType = CatalogOrderType.ORDER_DESC;
                break;
            case ORDER_DESC:
                mIvCatalogOrder.setImageResource(R.mipmap.ic_read_catalog_order_asc);
                mTvCatalogOrder.setText(getResources().getString(R.string.wa_read_catalog_order_asc));
                mCatalogOrderType = CatalogOrderType.ORDER_ASC;
                break;
        }
        mCatalogAdapter.reverseItems();
//        chapterToMap(mCatalogAdapter.getItems());
        mCatalogAdapter.notifyDataSetChanged();

    }

    private void initRecyclerViewEvent() {

//        mRvRead.setOnClickListener(v -> toggleMenu(true));
//        mRvRead.setOnTouchListener(new View.OnTouchListener() {
//            @Override
//            public boolean onTouch(View v, MotionEvent event) {
//                return false;
//            }
//        });
        mRvRead.setTouchListener((x, y) -> {

            if (mAblTopMenu.getVisibility() == View.VISIBLE) {
                toggleMenu(true);
            }else if (0.333 < x && x < 0.666) {
                toggleMenu(true);
            }

        });
//        mRvRead.setTouchListener((v, event) ->
//                toggleMenu(true)
//        );
        mComicReadAdapter.setOnItemChildClickListener((adapter, view, position) -> {
            if (!(Boolean) view.getTag(R.id.iv_tag)) {
                //TODO
                ToastUtils.show("失败了，需要retry");
            } else {
                ToastUtils.show("成功了？");
                toggleMenu(true);
            }
        });
        mComicReadAdapter.setOnItemClickListener((adapter, view, position) -> {
            ToastUtils.show("on item click");
        });
    }

    @Override
    protected void initEvent() {
        super.initEvent();

//        initRvEvent();
        initRecyclerViewEvent();
        initRvScrollEvent();
        initCatalogOrderEvent();


        mLvCatalog.setOnItemClickListener(
                (parent, view, position, id) -> {
                    mDlSlide.closeDrawer(GravityCompat.START);
                    //TODO
//                    mPageLoader.skipToChapter(position);
                    skipToChapter(position);

                }
        );

        mTvCatalog.setOnClickListener(
                (v) -> {
                    //移动到指定位置
                    if (mCatalogAdapter.getCount() > 0) {
                        //TODO
                        mLvCatalog.setSelection(getChapterIndexNow());
                    }
                    //切换菜单
                    toggleMenu(true);
                    //打开侧滑动栏
                    mDlSlide.openDrawer(GravityCompat.START);
                }
        );
//        mTvSetting.setOnClickListener(
//                (v) -> {
//                    toggleMenu(false);
//                    mSettingDialog.show();
//                }
//        );
        mTvDownload.setOnClickListener(
                (v) -> {
                    //先保存，在挑选章节
                    saveMedia();
                    MediaCatalogSelectActivity.startActivity(this, mCollectionMediaBean);
                }
        );

        mTvPreChapter.setOnClickListener(
                (v) -> {
                    skipToPreChapter();
//                    if(skipToPreChapter()) {
//                        mLvCatalog.setSelection(getChapterIndexNow());
//                    }
                }
        );

        mTvNextChapter.setOnClickListener(
                (v) -> {
                    //TODO
                    skipToNextChapter();
//                    if (skipToNextChapter()) {
//                        mLvCatalog.setSelection(getChapterIndexNow());
//                    }
                }
        );

        mTvNightMode.setOnClickListener(
                (v) -> {
                    if (isNightMode) {
                        isNightMode = false;
                        BrightnessUtils.setBrightness(this, 80);
                    } else {
                        BrightnessUtils.setBrightness(this, 5);
                        isNightMode = true;
                    }
                    //TODO
//                    mPageLoader.setNightMode(isNightMode);
                    toggleNightMode();
                }
        );

        //TODO
//        mTvBrief.setOnClickListener(
//                (v) -> MediaDetailActivity.startActivity(this, mBookId)
//        );
//
//        mTvCommunity.setOnClickListener(
//                (v) -> {
//                    Intent intent = new Intent(this, CommunityActivity.class);
//                    startActivity(intent);
//                }
//        );
        mTvChangeSource.setOnClickListener(v -> {
            saveRecord();
//            ChangeSourceActivity.startActivity(this, mCollectionMediaBean, getCurrentChapterTitle(), getCurrentPagePositionInChapter(), isCollected);
            mCollectionMediaBean.__setDaoSession(DaoDbHelper.getInstance().getSession());
            String currentChapterName = getCurrentChapterTitle();
            ChangeSourceActivity.startActivityForResult(REQUEST_CHANGE_SOURCE, this, mCollectionMediaBean, currentChapterName, 0, isCollected);
        });

        mSettingDialog.setOnDismissListener(
                dialog -> hideSystemBar()
        );
    }

    private void updateTips(String chapter, String page) {
        mTvChapter.setText(chapter);
        mTvPage.setText(page);
    }

    private void updateTips() {

        int firstItemPosition = mLayoutManager.findFirstVisibleItemPosition();
        firstItemPosition = firstItemPosition < 0 ? 0 : firstItemPosition;
        ChapterContentBo curPageFirstContentBo = mComicReadAdapter.getData().get(firstItemPosition);
        String chapterId = curPageFirstContentBo.getChapterId();
        int chapterIndex = getChapterIndexInRawData(chapterId);
        String chapter = mCatalogRawDataList.get(chapterIndex).getName();
        String page = (curPageFirstContentBo.getCurPartNum() + 1) + "/" + curPageFirstContentBo.getPartTotal();
        updateTips(chapter, page);

        //TODO 反转
        mCatalogAdapter.setChapter(getChapterIndexNow());
    }

    private void updateTipsTime() {
        String time = StringUtils.dateConvert(System.currentTimeMillis(), WaConstants.FORMAT_TIME);
        mTvTime.setText(time);

    }

    /**
     * 保存阅读信息
     */
    public void saveRecord() {
        if (mCatalogAdapter.getItems().isEmpty() || mComicReadAdapter.getData().isEmpty()) {
            return;
        }
        mMediaRecordBean.setMediaId(mCollectionMediaBean.getId());
        int firstItemPosition = mLayoutManager.findFirstVisibleItemPosition();
        Integer chapterIndex = mChapterIndexRawMap.get(mComicReadAdapter.getData().get(firstItemPosition).getChapterId());
        chapterIndex = chapterIndex == null ? 0 : chapterIndex;
        mMediaRecordBean.setChapter(chapterIndex);

        int curPageNum = mComicReadAdapter.getData().get(firstItemPosition).getCurPartNum();
        mMediaRecordBean.setPagePos(curPageNum);

        //存储到数据库
        MediaStorageManager.getInstance()
                .saveMediaRecordAsync(mMediaRecordBean);
        RxBus.get().post(RxEvent.MEDIA_COLLECTION_REFRESH, mCollectionMediaBean);
    }

    //获取现在的章节index
    private int getChapterIndexNow() {
        int first = mLayoutManager.findFirstVisibleItemPosition();
        first = first <= 0 ? 0 : first;
        String chapterId = mChapterContentBoList.get(first).getChapterId();
        int rawIndex = getChapterIndexInRawData(chapterId);
        return getChapterIndexInRawData(rawIndex);
    }

    //获取当前章节的首张图片的页码
    private int getCurrentPagePositionInChapter() {
        try {
            int first = mLayoutManager.findFirstVisibleItemPosition();
            return mComicReadAdapter.getData().get(first).getCurPartNum();
        } catch (Exception e) {
            return 0;
        }

    }

    private String getCurrentChapterTitle() {
        if (mCatalogRawDataList == null || mCatalogRawDataList.isEmpty()) {
            return null;
        }
        return mCatalogRawDataList.get(getChapterIndexInRawData()).getName();
    }

    //获取现在的章节index
    private int getChapterIndexInRawData() {
        if (mChapterContentBoList == null || mChapterContentBoList.isEmpty()) {
            return 0;
        }
        int first = mLayoutManager.findFirstVisibleItemPosition();
        String chapterId = mChapterContentBoList.get(first).getChapterId();
        return getChapterIndexInRawData(chapterId);
    }

    private int getChapterIndexInRawData(String chapterId) {
        if (mChapterIndexRawMap.isEmpty()) {
            return 0;
        }
        Integer index = mChapterIndexRawMap.get(chapterId);
        index = index == null ? 0 : index;
        return index;
//        if (mCatalogOrderType == CatalogOrderType.ORDER_ASC) {
//
//            return index;
//        } else {
//            return mChapterIndexRawMap.size() - index - 1;
//        }
    }

    private int getChapterIndexInRawData(int curPosition) {
        if (mCatalogOrderType == CatalogOrderType.ORDER_ASC) {
            return curPosition;
        } else {
            return mChapterIndexRawMap.size() - curPosition - 1;
        }
    }

    private void loadPrevChapter() {
        int firstItemPosition = mLayoutManager.findFirstVisibleItemPosition();
        if (mComicReadAdapter.getData().isEmpty()) {
            return;
        }
        firstItemPosition = firstItemPosition <= 0 ? 0 : firstItemPosition;
        ChapterContentBo curPageFirstContentBo = mComicReadAdapter.getData().get(firstItemPosition);

        String chapterId = curPageFirstContentBo.getChapterId();
        int chapterIndex = getChapterIndexInRawData(chapterId);
        if (chapterIndex > 0) {
            mPresenter.loadChapter(mSiteSourceBean, mCollectionMediaBean, mCatalogRawDataList.subList(chapterIndex - 1, chapterIndex), ComicLoadFlag.LOAD_PRE);
        } else {
            //TODO 到第一章了，显示 已经是第一章了哦
        }
    }

    private void loadNextChapter() {
        int lastItemPosition = mLayoutManager.findLastVisibleItemPosition();
        if (mComicReadAdapter.getData().isEmpty()) {
            return;
        }
        if (lastItemPosition >= mComicReadAdapter.getData().size() - 1) {
            lastItemPosition = mComicReadAdapter.getData().size() - 1;
        }
        ChapterContentBo curPageLastContentBo = mComicReadAdapter.getData().get(lastItemPosition);
        String chapterId = curPageLastContentBo.getChapterId();
        int chapterIndex = getChapterIndexInRawData(chapterId);

        if (chapterIndex < mCatalogRawDataList.size() - 1) {
            mPresenter.loadChapter(mSiteSourceBean, mCollectionMediaBean, mCatalogRawDataList.subList(chapterIndex + 1, chapterIndex + 2), ComicLoadFlag.LOAD_NEXT);
        } else {
            //TODO 到最后章了，显示 没有更多内容了哦
        }
    }

    private void initRvScrollEvent() {
        mRvRead.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                switch (newState) {
                    case RecyclerView.SCROLL_STATE_DRAGGING:
                        hideReadMenu();
                        mDlSlide.closeDrawer(GravityCompat.START);
                        break;
                    case RecyclerView.SCROLL_STATE_IDLE:
                    case RecyclerView.SCROLL_STATE_SETTLING:
                        int firstItemPosition = mLayoutManager.findFirstVisibleItemPosition();
                        if (firstItemPosition < 3) {
                            loadPrevChapter();
                        }
                        int lastItemPosition = mLayoutManager.findLastVisibleItemPosition();
                        if (lastItemPosition == mChapterContentBoList.size() - 1) {
                            loadNextChapter();
                        }
                        break;
                }
            }

            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);

                if (Math.abs(dy) > 5) {
                    updateTips();
                }
//                try {
//                    if (Math.abs(dy) < 1) {
//                        return;
//                    }
//                    if (Math.abs(dy) > 5) {
//                        hideReadMenu();
//                        mDlSlide.closeDrawer(GravityCompat.START);
//                    }
//                    int firstItemPosition = mLayoutManager.findFirstVisibleItemPosition();
//                    int lastItemPosition = mLayoutManager.findLastVisibleItemPosition();
//                    ChapterContentBo curPageFirstContentBo = mComicReadAdapter.getData().get(firstItemPosition);
//                    ChapterContentBo curPageLastContentBo = mComicReadAdapter.getData().get(lastItemPosition);
//                    ChapterContentBo oldContentBo = mComicReadAdapter.getData().get(mLastTopPosition);
//
//                    String chapterId = curPageFirstContentBo.getChapterId();
//                    int preChapterIndex = -1;
//                    int nextChapterIndex = -1;
//                    String preChapterId;
//                    String nextChapterId;
//                    int chapterIndex = getChapterIndexInRawData(chapterId);
//                    if (chapterIndex > 0) {
//                        preChapterIndex = chapterIndex - 1;
//                        nextChapterIndex = chapterIndex + 1;
//                    }
//
//                    if (firstItemPosition != mLastTopPosition) {
//                        if (chapterIndex >= 0 && chapterIndex < mCatalogRawDataList.size()) {
//                            String chapter = mCatalogRawDataList.get(chapterIndex).getName();
//                            String page = (curPageFirstContentBo.getCurPartNum() + 1) + "/" + curPageFirstContentBo.getPartTotal();
//                            updateTips(chapter, page);
//                        }
//                        if (!oldContentBo.getChapterId().equals(curPageFirstContentBo.getChapterId())) {
//                            //章节切换了更新menu信息
//                            //save record
//                            saveRecord();
//
//                        } else {
//                            //判断前后章节的数据是否存在
//                            if (dy < -10) {
//                                //TODO 1.检查当前的上一章是否已经加载
//                                //     2.presenter 加载
//                                // 已经加载的chapter需要一个hashmap, chapterId -> chapterIndex
//                                if (curPageFirstContentBo.getCurPartNum() < LOAD_PRE_THRESHOLD) {
//                                    //load pre
//                                    if (firstItemPosition >= LOAD_PRE_THRESHOLD) {
//                                        //判断当前数据中的前一个章节内容，是不是真正的当前章节的前一个章节内容
//                                        //因为可能是从目录中点击跳转直接观看的，数据有断层
//                                        //不会有断层了，目录点击的话，直接就是清空了再添加
//
//                                        if (preChapterIndex > -1) {
//                                            preChapterId = mComicReadAdapter.getData().get(preChapterIndex).getChapterId();
//                                            String curPreChapterIdInData = mComicReadAdapter.getData().get(firstItemPosition - curPageFirstContentBo.getCurPartNum()).getChapterId();
//                                            if (!preChapterId.equals(curPreChapterIdInData)) {
//                                                mPresenter.loadChapter(mSiteSourceBean, mComicId, mCatalogRawDataList.subList(preChapterIndex, preChapterIndex + 1), ComicLoadFlag.LOAD_PRE);
//                                            }
//                                        }
//                                    } else {
//                                        //如果当前章节数目都不够了，那么一定需要加载新的
//                                        mPresenter.loadChapter(mSiteSourceBean, mComicId, mCatalogRawDataList.subList(preChapterIndex, preChapterIndex + 1), ComicLoadFlag.LOAD_PRE);
//                                    }
//
//                                }
//
//
//                            } else if (dy > 10) {
//                                //TODO 1.检查当前的下一章是否已经加载
//                                //     2.presenter 加载
//                                int curPageImgLeft = curPageLastContentBo.getPartTotal() - curPageLastContentBo.getCurPartNum();
//                                if (curPageImgLeft < LOAD_NEXT_THRESHOLD) {
//                                    //当前章节已经快完了，判断下一个逻辑章节是否已经加载
//                                    if (lastItemPosition + curPageImgLeft < mComicReadAdapter.getData().size()) {
//                                        //data里面还有多余的图片章节，要判断是不是当前章节的下一章节
//                                        if (nextChapterIndex < mChapterIndexRawMap.size()) {
//                                            nextChapterId = mComicReadAdapter.getData().get(nextChapterIndex).getChapterId();
//                                            String curNextChapterIdInData = mComicReadAdapter.getData().get(lastItemPosition + curPageImgLeft).getChapterId();
//                                            if (!nextChapterId.equals(curNextChapterIdInData)) {
//                                                mPresenter.loadChapter(mSiteSourceBean, mComicId, mCatalogRawDataList.subList(nextChapterIndex, nextChapterIndex + 1), ComicLoadFlag.LOAD_NEXT);
//                                            }
//                                        }
//                                    } else {
//
//                                        mPresenter.loadChapter(mSiteSourceBean, mComicId, mCatalogRawDataList.subList(nextChapterIndex, nextChapterIndex + 1), ComicLoadFlag.LOAD_NEXT);
//                                    }
//                                }
//
//
//                            }
//                        }
//
//                    }
//
//
//                    mLastTopPosition = firstItemPosition;
//                    mLastBottomPosition = lastItemPosition;
//                } catch (Exception e) {
//                    e.printStackTrace();
//                }
            }
        });
    }

    /**
     * 加载上一章的数据
     */
    private void loadPreData() {

    }

    private void initRvEvent() {
        mRvRead.addOnItemTouchListener(new RecyclerView.SimpleOnItemTouchListener() {
            private int mStartX = 0;
            private int mStartY = 0;
            private boolean isMove = false;
            private boolean canTouch = true;
            // 唤醒菜单的区域
            private RectF mCenterRect = null;

            @Override
            public boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {
                return false;
            }

            @Override
            public void onTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent event) {

                int x = (int) event.getX();
                int y = (int) event.getY();
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        mStartX = x;
                        mStartY = y;
                        isMove = false;
                        canTouch = !hideReadMenu();
                        break;
                    case MotionEvent.ACTION_MOVE:
                        // 判断是否大于最小滑动值。
                        int slop = ViewConfiguration.get(ComicReadActivity.this).getScaledTouchSlop();
                        if (!isMove) {
                            isMove = Math.abs(mStartX - event.getX()) > slop || Math.abs(mStartY - event.getY()) > slop;
                        }

                        break;
                    case MotionEvent.ACTION_UP:
                        if (!isMove) {
                            //设置中间区域范围
                            if (mCenterRect == null) {
                                int width = DisplayUtil.getScreenWidth(ComicReadActivity.this);
                                int height = DisplayUtil.getScreenHeight(ComicReadActivity.this);
                                mCenterRect = new RectF(width / 5.0f, height / 3.0f,
                                        width * 4 / 5.0f, height * 2 / 3.0f);
                            }

                            //是否点击了中间
                            if (mCenterRect.contains(x, y)) {
                                toggleMenu(true);
                            }
                        }
                        break;
                    default:
                        break;
                }
            }

            @Override
            public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

            }
        });

    }


    @Override
    public void errorChapter() {
        //TODO 有误，请重试
        llLoading.setVisibility(GONE);

    }

    @Override
    public void lazyLoadSuccess(ChapterContentBo chapterContentBo) {
        //懒加载的图片成功
        mComicReadAdapter.lazyLoadSuccess(chapterContentBo);
        //更新chapter content内容
        String chapterId = chapterContentBo.getChapterId();
        Integer chapterIndex = mChapterIndexRawMap.get(chapterId);
        if (chapterIndex == null) {
            return;
        }
        if (mCatalogAdapter.getItems().isEmpty()) {
            return;
        }
        String chapterTitle = mCatalogAdapter.getItems().get(chapterIndex).getName();
        if (org.apache.commons.lang3.StringUtils.isEmpty(chapterTitle)) {
            return;
        }
        mPresenter.saveChapterLazyContent(mCollectionMediaBean.getId(), chapterTitle, chapterContentBo);


    }

    @Override
    public void lazyLoadFailed(ChapterContentBo chapterContentBo) {
        //TODO
    }

    @Override
    public void showError() {

    }

    @Override
    public void complete() {

    }

    /**
     * 隐藏阅读界面的菜单显示
     *
     * @return 是否隐藏成功
     */
    private boolean hideReadMenu() {
        hideSystemBar();
        if (mAblTopMenu.getVisibility() == VISIBLE) {
            toggleMenu(true);
            return true;
        } else if (mSettingDialog.isShowing()) {
            mSettingDialog.dismiss();
            return true;
        }
        return false;
    }

    //    @Override
    public boolean onTouch(View view, MotionEvent event) {


//        if (!canTouch && event.getAction() != MotionEvent.ACTION_DOWN) return true;
        int x = (int) event.getX();
        int y = (int) event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mStartX = x;
                mStartY = y;
                isMove = false;
                canTouch = !hideReadMenu();
                break;
            case MotionEvent.ACTION_MOVE:
                // 判断是否大于最小滑动值。
                int slop = ViewConfiguration.get(this).getScaledTouchSlop();
                if (!isMove) {
                    isMove = Math.abs(mStartX - event.getX()) > slop || Math.abs(mStartY - event.getY()) > slop;
                }

                break;
            case MotionEvent.ACTION_UP:
                if (!isMove) {
                    //设置中间区域范围
                    if (mCenterRect == null) {
                        int width = DisplayUtil.getScreenWidth(this);
                        int height = DisplayUtil.getScreenHeight(this);
                        mCenterRect = new RectF(width / 5.0f, height / 3.0f,
                                width * 4 / 5.0f, height * 2 / 3.0f);
                    }

                    view.performClick();
                    //是否点击了中间
                    if (mCenterRect.contains(x, y)) {
                        toggleMenu(true);
                        return true;
                    }
                }
                break;
            default:
                break;
        }
        return false;
    }

    @Override
    public void onPhotoTap(ImageView view, float x, float y) {

        toggleMenu(true);
//        if (0.333 < x && x < 0.666) {
//            toggleMenu(true);
//        } else {
//            //TODO pre && next
//            hideReadMenu();
//        }
    }

    @Override
    public void lazyLoad(ChapterContentBo chapterContentBo) {

        mPresenter.lazyLoadImage(mSiteSourceBean, mCollectionMediaBean, chapterContentBo);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_reader, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_detail) {
            mCollectionMediaBean.__setDaoSession(DaoDbHelper.getInstance().getSession());
            MediaDetailActivity.startActivity(this, mCollectionMediaBean, inputChapterBeanList);
        } else if (id == R.id.action_view_by_browser) {

            if (mCatalogRawDataList == null || mCatalogRawDataList.isEmpty()) {
                return false;
            }
            String url = mCatalogRawDataList.get(getChapterIndexInRawData()).getLink();
            openUrl(url);
        }
        return super.onOptionsItemSelected(item);
    }

    public void openUrl(String url) {
        Intent intent = new Intent();
        intent.setData(Uri.parse(url));//Url 就是你要打开的网址
        intent.setAction(Intent.ACTION_VIEW);
        this.startActivity(intent); //启动浏览器
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode != RESULT_OK) {
            LogUtils.e("BookReadActivity onActivityResult ,resultCode not ok, is " + resultCode);
            return;
        }
        hideReadMenu();
        if (requestCode == REQUEST_CHANGE_SOURCE) {
            inputChapterBeanList = null;
            inputChapterId = null;
            inputChapterTitle = getCurrentChapterTitle();
            inputChapterIndex = getChapterIndexInRawData();
            MediaStorageManager.getInstance().deleteCollBook(mCollectionMediaBean);

            mCollectionMediaBean = data.getParcelableExtra("bean");
            mCollectionMediaBean.__setDaoSession(DaoDbHelper.getInstance().getSession());
            mSiteSourceBean = mCollectionMediaBean.getSiteSourceBean();
            mCollectionMediaBean.setMediaChapterList(new ArrayList<>());
            MediaStorageManager.getInstance().saveCollectionMedia(mCollectionMediaBean);
            RxBus.get().post(RxEvent.MEDIA_COLLECTION_REFRESH, mCollectionMediaBean);

            mCatalogAdapter.clear();
            int size = mComicReadAdapter.getData().size();
            mComicReadAdapter.getData().clear();
            mComicReadAdapter.notifyItemMoved(0, size);
            mChapterContentBoList.clear();
            mCatalogRawDataList.clear();
            mChapterIndexRawMap.clear();

            startLogic();


        }


    }

    @Subscribe(thread = EventThread.IO,
            tags = {@Tag(RxEvent.DOWNLOADED_FILE_DELETED)})
    public void onDownloadTaskStatusChanged(ArrayList<DownloadTaskBean> taskBeanList) {
        for (DownloadTaskBean taskBean : taskBeanList) {
            if (taskBean.getMediaId() != null && taskBean.getMediaId().equals(mCollectionMediaBean.getId())) {
                //删除的包括当前漫画的内容，需要重新加载下一页
                loadPrevChapter();
                loadNextChapter();

            }
        }

    }
}
